#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2021/11/10 16:43
# @Author  : huidong.bai
# @File    : speaker_monitor.py
# @Software: PyCharm
import logging
import os
import subprocess

import serial
import serial.tools.list_ports
# import win32com.client
# import datetime

logger = logging.getLogger('django')

ADB_LINUX = 0
RTOS = 1
ADB_ANDROID = 2
ADB_PID_VID = 'VID_2207&PID_0006\\\\'
CH340_PID_VID = 'VID_1A86&PID_7523\\\\'
linux_speaker_rom_version_cmd = 'adb -s %s shell cat version_usr'
linux_speaker_ping_baidu = 'adb -s %s shell ping www.baidu.com -c1'


def get_devices_list():
    logger.info('查询设备列表中...')
    device_list = []

    # wmi = win32com.client.GetObject("winmgmts:")
    # for usb in wmi.InstancesOf("win32_usbcontrollerdevice"):
    #     if ADB_PID_VID in usb.Dependent:
    #         infos = {'device_type': ADB_LINUX, 'port': usb.Dependent.split(ADB_PID_VID)[1][:-1]}
    #         device_list.append(infos)
    #     # if CH340_PID_VID in usb.Dependent:
    #     #     infos = {'device_type': 'COM', 'port': usb.Dependent.split(CH340_PID_VID)[1][:-1]}
    #     #     devices.append(infos)

    pop = subprocess.Popen('adb devices', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    lines = pop.stdout.readlines()
    for line in lines:
        if '\\tdevice' in str(line):
            # 编码转换，标准输出字节流转string
            log = line.decode("UTF-8", "ignore")
            device_sn = log.split('\t')[0]
            infos = {'device_type': ADB_LINUX, 'port': device_sn}
            device_list.append(infos)

    ports = list(serial.tools.list_ports.comports())
    if len(ports) > 0:
        for each_port in ports:
            if "USB-SERIAL" in each_port[1]:
                com = each_port[0]
                infos = {'device_type': RTOS, 'port': com}
                device_list.append(infos)

    return device_list


def get_speaker_infos(com_list):
    logger.info('数据库中的列表为：%s' % com_list)
    device_list = get_devices_list()
    for item in device_list:
        if item.get('device_type') == ADB_LINUX:
            version_cmd = linux_speaker_rom_version_cmd % item.get('port')
            pop = os.popen(version_cmd).readlines()
            if len(pop) == 0:
                logger.error('查询信息失败，请检查：%s' % item.get('port'))
                continue
            item['sn'] = item.get('port')
            item['rom_version'] = pop[0].split('\n')[0]
            item['detail'] = pop[2].split('\n')[0]
        if item.get('device_type') == RTOS:
            port = item.get('port')

            # 如果redis数据库中存在数据，则不读取信息数据
            if any(key in port for key in com_list):

                continue

            return_val = read_serial(port)

            if return_val == '':
                logger.error("can't open the serial port,please checkout it")
                continue

            sn, rom_version = read_infos(return_val)
            if sn == '' or rom_version == '':
                logger.warning('查询sn, rom_version失败，请检查：%s' % port)
                continue
            item['sn'] = sn
            item['rom_version'] = rom_version
            item['detail'] = '串口设备'
    return device_list


def read_serial(com_port):
    long_str_info = ''
    try:
        ser = serial.Serial(com_port, '115200', timeout=4)
        cmd = 'sys no\nsys id\nsys app\n'
        ser.write(cmd.encode())

        line_cont = 0
        # 抓取15行日志
        while line_cont < 15:
            line = ser.readline().strip()
            log = line.replace(b'\\\\x', b'%').decode("UTF-8", "ignore")
            long_str_info += log
            line_cont += 1

        return long_str_info
    except Exception as e:
        logger.error('open the serial failed,please checkout it!')
        return ''


def read_infos(log_str):
    sn = ''
    rom_version = ''
    for i in log_str.split('>'):
        if 'sys id' in i:
            sn = i.split('sys id')[1]
        elif 'sys app' in i:
            rom_version = i.split('sys app')[1]

    return sn, rom_version


def get_adb_infos(port):
    version_cmd = linux_speaker_rom_version_cmd % port
    pop = os.popen(version_cmd).readlines()
    if len(pop) == 0:
        logger.error('查询信息失败，请检查：%s' % port)
        return None
    item = {'sn': port, 'rom_version': pop[0].split('\n')[0], 'detail': pop[2].split('\n')[0]}
    return item


def get_serial_infos(port):
    return_val = read_serial(port)

    if return_val == '':
        logger.error("can't open the serial port,please checkout it")
        return None

    sn, rom_version = read_infos(return_val)
    if sn == '' or rom_version == '':
        logger.warning('查询sn, rom_version失败，请检查：%s' % port)
        return None
    item = {'sn': sn, 'rom_version': rom_version, 'detail': '串口设备'}
    return item
